package com.DGT.OCRAdjuntosCorreo;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;


import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;


import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;
import javax.mail.Part;

import net.sourceforge.jtocr.Gui;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.*;

import com.DGT.OCRCAjuntosCorreo.Utils.*;
import org.apache.log4j.BasicConfigurator;

public class LectorCorreoAdjuntos {
	
	private Logger logger = Logger.getLogger(getClass().getName());
	static boolean configurator=false;
	Folder inbox;
	Message messages[];
    FetchProfile fp;
    String ayer=null;
    Multipart multi=null;
    ArrayList<Message> correosConAdjunto=new ArrayList<Message>();
    Gui gui = new Gui();
    boolean analizarDocs=false;
    AlertasDAO alertas = new AlertasDAO();
    
    
	public LectorCorreoAdjuntos() throws IOException {
		
		boolean flag=false;
		ArrayList<Boolean> hayPdf = new ArrayList<Boolean>();
		Store store=null;
		Folder inbox=null;
		String direccion=UtilsOCR.getPropertiesPaths().getProperty("DIRECCION_CORREO");
		String password=UtilsOCR.getPropertiesPaths().getProperty("PASSWORD_CORREO");
		
		
		try{
			Properties props = new Properties();
			props.setProperty("mail.imap.port", "993");
			props.setProperty("mail.store.protocol", "imaps");
			Session session = Session.getInstance(props, null);
			store = session.getStore("imaps");
			store.connect("imap.gmail.com",direccion, password);
		}
		catch(Exception e){
			logger.error("error en la conexion: "+e.getMessage());
		}
		
		while(!flag){
			try {
				logger.info("=============Comenzando a leer correos===============");
				inbox = store.getFolder("Inbox");
				inbox.open(Folder.READ_ONLY);
				logger.info("numero de mensajes no leidos: "+ inbox.getUnreadMessageCount() + " de un total de: "+ inbox.getMessageCount());;
				Flags seen = new Flags(Flags.Flag.SEEN);
				FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
				messages = inbox.search(unseenFlagTerm);
				
				for (int i = 0; i < messages.length; i++) {
					if(messages[i].isMimeType("multipart/*")){
						hayPdf.add(mensajeConAdjuntos(messages[i]));					
					}
				}
				if(!hayPdf.contains(true)){
					logger.info("no hay pdf adjuntos en la bandeja de entrada");
					hayPdf.clear();
				}
				else{
					hayPdf.clear();
					/*Una vez descagados todos os adjuntos a la carpeta temporal, procedemos a recorrela para mover los archivos
					 * a sus correspondientes destinatarios*/
					gui.TimerDirectory();		//solo si hemos encontrado pdf iniciamos el OCR
				}
			} catch (Exception e) {
				logger.error("Error: "+ e.getMessage());
				flag=true;
			}

			logger.info("=========================Lectura de correo finalizada============================\n");
			
			gui.TimerDirectoryEscaneos();
			logger.info("=========================Lectura del directorio escaneos finalizada============================\n");
			try {
				  Thread.sleep(1000*30);			//Integer.parseInt(UtilsOCR.getPropertiesPaths().getProperty("FRECUENCIA_MIN_LEER_CORREOS"));
			} 
			catch (InterruptedException ie) {
				    //Handle exception
			}
		}
		try {
			inbox.close(true);
			store.close();
		} catch (Exception ex) {
			logger.error("error al cerrar la conexion: " + ex.getMessage());
		}			
	}
    
	
	public Boolean mensajeConAdjuntos(Message mensaje) throws MessagingException, IOException, SQLException{
		ArrayList<Boolean> hayAdjuntos=new ArrayList<Boolean>();
		boolean adjuntosPdf=false;

		multi=(Multipart) mensaje.getContent();		//obtenemos los adjuntos del mensaje para recorrerlos posteriormentee
		for(int i=0;i<multi.getCount();i++){
			Part parte=multi.getBodyPart(i);
			if(parte.isMimeType("application/pdf") || parte.isMimeType("image/jpeg") || parte.isMimeType("image/png")){
				hayAdjuntos.add(true);
				try{
					logger.info("encontrado un correo con PDF adjuntos");
					if(!documentoExisteEnCarpetaTemporal(parte.getFileName()) && !alertas.existeAlertaParaDocuementoMismoNombre(parte.getFileName())){
						moverAdjuntoCarpetaTemporal(parte);
					}
					else{
						logger.info("El documento "+parte.getFileName()+" ya ha sido descargado previamente.Omitiendo...");
					}
				}
				catch(Exception e){
					logger.error("error al mover el mensaje a la carpeta de su destinatario"+e.getMessage());
				}
			}
			else{
				hayAdjuntos.add(false);
			}
		}
		if(hayAdjuntos.contains(true)){
			adjuntosPdf=true;		
		}
		return adjuntosPdf;
	}
	
	public void moverAdjuntoCarpetaTemporal(Part Fichero)throws IOException, MessagingException{
		String fileDestPath=UtilsOCR.getPropertiesPaths().getProperty("DIRECTORIO_TEMPORAL")+File.separator;
		File directorioDestino = new File(fileDestPath);
		
		if(!directorioDestino.exists()){
			directorioDestino.mkdir();
		}
		
		FileOutputStream output = new FileOutputStream(fileDestPath+Fichero.getFileName());//--------evitar copiar un arhivo que ya existee
		InputStream input = Fichero.getInputStream();
		
		try{
			logger.info("moviendo el adjunto "+Fichero.getFileName()+" hacia "+fileDestPath);
			byte[] buffer = new byte[4096];
			int byteRead;
	
			while ((byteRead = input.read(buffer)) != -1) {
			    output.write(buffer, 0, byteRead);
			}
		}
		catch(Exception e){
			logger.info("error al copiar el archivo "+e.getMessage());
		}
		output.close();
	}
	
	public boolean documentoExisteEnCarpetaTemporal(String adjunto){
		File temporal = new File( UtilsOCR.getPropertiesPaths().getProperty("DIRECTORIO_TEMPORAL"));
		File[] archivos =temporal.listFiles();
		boolean existe=false;

		for(File doc: archivos){
			if(doc.getName().equals(adjunto)){
				existe=true;	}
		}
		return existe;
	}
	
	/*public boolean correoYaAnalizado(String nombreCorreo) throws IOException{
		boolean correoAnalizado=false;
		try{
			File registroCorreos = new File( UtilsOCR.getPropertiesPaths().getProperty("DIRECTORIO_TEMPORAL")+File.separator+"ListadoCorreosAnalizados.txt");
			if(!registroCorreos.exists()){
				registroCorreos.createNewFile();
			}
			if(FileUtils.readFileToString(registroCorreos).contains(nombreCorreo)){
				correoAnalizado=true;
			}
			else{
				FileUtils.writeStringToFile(registroCorreos, nombreCorreo, true);
			}
		}
		catch(Exception e){
			logger.error("Error a el archivo de registro "+e.getMessage());
		}
		
		return correoAnalizado;
	}*/
	
	public static void main(String[] args) throws IOException,MessagingException{
		if(!Logger.getRootLogger().getAllAppenders().hasMoreElements()){		//con esto se evita la duplicidad de mensajes al ejecutar el jar
			BasicConfigurator.configure();
		}		
		
		System.out.println("iniciando.....");
		new LectorCorreoAdjuntos();
		System.out.println("Finalizado.");
	}
}

